#ifndef _U_SERVER_H_
#define _U_SERVER_H_

#include <QtWidgets/QWidget>
#include <QUdpSocket>
#include <QHostAddress>
#include <QSqlDatabase>
#include <QSettings>

enum class OPERATOR
{
    SAMEINFO,//返回相同信息
    JSONINFO, //获取default.json文件内容
    UPDATEINFO,
    ADDBOOK,
    QUERYBOOK,
    DELETEBOOK,
    REVISEBOOK,
    UNKNINFO
};
class UBooksInfo;
class UServer : public QObject
{
    Q_OBJECT
public:
    UServer(QWidget *parent = nullptr);
    ~UServer();
    OPERATOR getOperatorType(const QByteArray& byteArray);
    QByteArray getData(const QByteArray& byteArray);
    QByteArray ReadJsonToByteArray(const QString& filename);
    void readConfig();
    quint16 port;

private slots:
    void onServerReadyRead();

private:
    void returnSameInfo(const QByteArray& datagram, QHostAddress& ip, quint16 port);        //向客户端发送数据段
    void returnJsonFile(QHostAddress &sender, quint16 &senderPort);                         //向客户端发送JSON文件内容
    void writeJsonToFile(const QByteArray& datagram, QHostAddress& ip, quint16 port);       //写入文件
    void addBookToDatabase(const QByteArray& datagram, QHostAddress& ip, quint16 port);     //向数据库添加内容
    void queryBookFromDatabase(const QByteArray& datagram, QHostAddress& ip, quint16 port); //查询数据库的书籍
    void deleteBookFromDatabase(const QByteArray& datagram, QHostAddress& ip, quint16 port);//删除数据库的书籍(暂时单个删除)
    void reviseBookFrmoDatabase(const QByteArray& datagram, QHostAddress& ip, quint16 port);//修改数据库的书籍(暂时单个修改)
    //删除数据库的书籍

    QUdpSocket* udpSocket;
  

    template<typename T>// 基础模板，用于递归终止  
    void writeToByteArray(QDataStream& dataStream, T&& arg)
    {
        dataStream << std::forward<T>(arg);
    }
    template<typename T, typename... Args>// 递归模板，用于处理多个参数  
    void writeToByteArray(QDataStream& dataStream, T&& first, Args&&... args)
    {
        dataStream << std::forward<T>(first);
        if (sizeof...(args) > 0)writeToByteArray(dataStream, std::forward<Args>(args)...);
    }
    template<typename... Args>// 封装函数，便于调用  
    QByteArray serialize(Args&&... args)
    {
        QByteArray byteArray;
        QDataStream dataStreamData(&byteArray, QIODevice::WriteOnly);
        writeToByteArray(dataStreamData, std::forward<Args>(args)...);
        return byteArray;
    }
};

#endif